package com.flying.io;

import org.junit.jupiter.api.Test;

import java.io.*;
import java.util.zip.CheckedOutputStream;

/**
 * @author 刘鹏飞
 * @ClassName TestFileBufferStream
 * @Date 2025/2/16 09:27
 * @Created by 刘鹏飞
 * @Description  测试 缓冲字节流
 * Java缓冲流本身并不具有IO流的读取与写入功能，
 * 只是在别的流（节点流或其他处理流）上加上缓冲功能提高效率，就像是把别的流包装起来一样，因此缓冲流是一种处理流（包装流）。
 *
 * BufferedInputStream和BufferedOutputStream这两个流是缓冲字节流，通过内部缓存数组来提高操作流的效率。
 *
 * 后开先闭原则:
 * 在关闭流时，应该先关闭最外层的包装流，即“后开的先关闭”。
 * 缓存区的大小默认是8192字节，也可以使用其它的构造方法自己指定大小。
 *
 */

public class TestFileBufferStream {

    public static void main(String[] args) {

        long start = System.currentTimeMillis();
        copyBufferStream("image/1.png","2.png");
        long end = System.currentTimeMillis();

        System.out.println(end-start);


    }


    //  使用文件缓冲字节流

    public static void copyBufferStream(String src,String back){

        // 定义流
        // 缓冲流的默认缓冲区大小是 8192
        try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(src));
            BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(back));
        ){
            int temp=0;
            while ((temp=bis.read())!=-1){
                bos.write(temp);
            }
            // 刷新内存
            // flush() 的作用
            //确保数据写入：确保所有在缓冲区中的数据都被写入到目标文件中，而不只是保留在内存中的缓冲区中。
            //立即刷新：立即刷新缓冲区，使得数据可以被其他程序或系统组件访问，而不是等待流被关闭时才刷新。
            //关闭前刷新：在关闭流之前，调用 flush() 确保所有数据都已经被写入，以防止数据丢失。

            // TODO
            //  在你提供的代码中，flush() 在 copyBufferStream 方法的最后被调用。这确保在方法完成之前，
            //  所有从 src 文件读取的数据都被写入到 back 文件中。但是，需要注意的是，在很多情况下，
            //  依赖于流的自动关闭机制（如你在代码中使用的 Java 7 的 try-with-resources 语法），
            //  系统在流关闭时会自动调用 close() 方法，而 close() 方法通常也会调用 flush() （
            //  除非流本身被配置为忽略 flush() 或 close() 操作）。因此，这里显式调用 flush() 可能是多余的，甚至可能会导致重复刷新。

            bos.flush();

        }catch(IOException e ){
            e.printStackTrace();
        }







        
    }








    // 不使用缓冲字节流
    /**
     * 通过创建一个指定长度的字节数组作为缓冲区，以此来提高IO流的读写效率。该方式适用于读取较大文件时的缓冲区定义。注意：缓冲区的长度一定是2的整数幂。一般情况下1024长度较为合适。
     * @param src
     * @param back
     */
    public static void copyFileBuffer(String src,String back){


        try (FileInputStream fis = new FileInputStream(src);
             FileOutputStream fos=new FileOutputStream(back);
        ) {

            byte[] buffer=new byte[1024];
            int temp=0;
            // temp 赋值为每次读入缓冲区的实际字节长度
            while ((temp=fis.read(buffer))!=-1){

                // 使用输入流将每次读入缓冲区的字节写入文件中
                fos.write(buffer,0,temp);
            }

            // 将内存数据写入文件中
            fos.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }


    }


}



